package io.geekidea.boot.util.dingtalk;

import cn.hutool.http.HttpStatus;
import com.alibaba.excel.util.StringUtils;
import com.alibaba.fastjson2.JSON;
import com.aliyun.dingtalkstorage_1_0.models.AddPermissionHeaders;
import com.aliyun.dingtalkstorage_1_0.models.AddPermissionRequest;
import com.aliyun.dingtalkstorage_2_0.models.AddPermissionRequest.AddPermissionRequestMembers;
import com.aliyun.dingtalkstorage_2_0.models.AddPermissionResponse;
import com.aliyun.dingtalkstorage_2_0.models.ListPermissionsResponse;
import com.aliyun.dingtalkstorage_2_0.models.ListPermissionsResponseBody.ListPermissionsResponseBodyPermissions;
import com.aliyun.teautil.models.RuntimeOptions;
import java.util.ArrayList;
import java.util.List;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class FilePermissionsUtil {

  /**
   * 使用 Token 初始化账号Client
   *
   * @return Client
   * @throws Exception
   */
  public static com.aliyun.dingtalkstorage_2_0.Client createClientV2() throws Exception {
    com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
    config.protocol = "https";
    config.regionId = "central";
    return new com.aliyun.dingtalkstorage_2_0.Client(config);
  }

  public static com.aliyun.dingtalkstorage_1_0.Client createClientV1() throws Exception {
    com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
    config.protocol = "https";
    config.regionId = "central";
    return new com.aliyun.dingtalkstorage_1_0.Client(config);
  }

  public static boolean addSpacePermissions(String accessToken, String spaceId, String unionId,
      String roleId, List<String> toUnionIdList, String corpId) {
    com.aliyun.dingtalkstorage_1_0.Client client = null;
    try {
      client = FilePermissionsUtil.createClientV1();
    } catch (Exception e) {
      log.error("错误消息：{}", e.getMessage(), e);
      return false;
    }

    AddPermissionHeaders addPermissionHeaders = new AddPermissionHeaders();
    addPermissionHeaders.xAcsDingtalkAccessToken = accessToken;
    List<AddPermissionRequest.AddPermissionRequestMembers> memberList = new ArrayList<>();
    for (String toUnionId : toUnionIdList) {
      AddPermissionRequest.AddPermissionRequestMembers member = new AddPermissionRequest.AddPermissionRequestMembers()
          .setType("USER")
          .setId(toUnionId)
          .setCorpId(corpId);
      memberList.add(member);
    }

    AddPermissionRequest addPermissionRequest = new AddPermissionRequest()
        .setUnionId(unionId)
        .setRoleId(roleId)
        .setMembers(memberList);
    try {
      log.debug("授权空间文件：{} 请求：{}", spaceId, JSON.toJSONString(addPermissionRequest));
      com.aliyun.dingtalkstorage_1_0.models.AddPermissionResponse resp = client.addPermissionWithOptions(
          spaceId, "0", addPermissionRequest, addPermissionHeaders, new RuntimeOptions());
      log.debug("授权空间文件：{} 返回：{}", spaceId, JSON.toJSONString(resp));
      if (resp.getStatusCode() == HttpStatus.HTTP_OK) {
        return resp.getBody().getSuccess();
      }
    } catch (Exception e) {
      log.error("请求：{} 错误消息：{}", JSON.toJSONString(addPermissionRequest), e.getMessage(), e);
    }
    return false;
  }

  /**
   * https://open.dingtalk.com/document/orgapp/add-permissions-file
   *
   * @param accessToken
   * @param fileUuid
   * @param unionId
   * @param userIdList
   * @param corpId
   * @return
   */
  public static boolean addPermissions(String accessToken, String fileUuid, String unionId,
      String roleId, List<String> userIdList,
      String corpId) {
    com.aliyun.dingtalkstorage_2_0.Client client = null;
    try {
      client = FilePermissionsUtil.createClientV2();
    } catch (Exception e) {
      log.error("错误消息：{}", e.getMessage(), e);
      return false;
    }

    com.aliyun.dingtalkstorage_2_0.models.AddPermissionHeaders addPermissionHeaders = new com.aliyun.dingtalkstorage_2_0.models.AddPermissionHeaders();
    addPermissionHeaders.xAcsDingtalkAccessToken = accessToken;

    List<AddPermissionRequestMembers> members = new ArrayList<>();
    for (String id : userIdList) {
      AddPermissionRequestMembers addPermissionRequestMembers = new AddPermissionRequestMembers();
      addPermissionRequestMembers.setId(id);
      addPermissionRequestMembers.setType("USER");
      addPermissionRequestMembers.setCorpId(corpId);
      members.add(addPermissionRequestMembers);
    }

    com.aliyun.dingtalkstorage_2_0.models.AddPermissionRequest addPermissionRequest = new com.aliyun.dingtalkstorage_2_0.models.AddPermissionRequest()
        .setUnionId(unionId)
        .setRoleId(roleId)
        .setMembers(members);
    try {
      log.debug("授权文件：{} 请求：{}", fileUuid, JSON.toJSONString(addPermissionRequest));
      AddPermissionResponse resp = client.addPermissionWithOptions(fileUuid, addPermissionRequest,
          addPermissionHeaders, new com.aliyun.teautil.models.RuntimeOptions());
      log.debug("授权文件：{} 返回：{}", fileUuid, JSON.toJSONString(resp));
      if (resp.getStatusCode() == HttpStatus.HTTP_OK) {
        return resp.getBody().getSuccess();
      }
    } catch (Exception e) {
      log.error("请求：{} 错误消息：{}", JSON.toJSONString(addPermissionRequest), e.getMessage(), e);
    }
    return false;
  }

  /**
   * https://open.dingtalk.com/document/orgapp/get-permission-list
   *
   * @param accessToken
   * @param dentryUuid
   * @param unionId
   * @return
   */
  public static List<ListPermissionsResponseBodyPermissions> listPermissions(String accessToken,
      String dentryUuid, String unionId) {
    com.aliyun.dingtalkstorage_2_0.Client client = null;
    try {
      client = FilePermissionsUtil.createClientV2();
    } catch (Exception e) {
      log.error("错误消息：{}", e.getMessage(), e);
      return null;
    }

    com.aliyun.dingtalkstorage_2_0.models.ListPermissionsHeaders listPermissionsHeaders = new com.aliyun.dingtalkstorage_2_0.models.ListPermissionsHeaders();
    listPermissionsHeaders.xAcsDingtalkAccessToken = accessToken;
    com.aliyun.dingtalkstorage_2_0.models.ListPermissionsRequest.ListPermissionsRequestOption option = new com.aliyun.dingtalkstorage_2_0.models.ListPermissionsRequest.ListPermissionsRequestOption();

    com.aliyun.dingtalkstorage_2_0.models.ListPermissionsRequest listPermissionsRequest = new com.aliyun.dingtalkstorage_2_0.models.ListPermissionsRequest()
        .setUnionId(unionId);
    try {
      ListPermissionsResponse resp = client.listPermissionsWithOptions(
          dentryUuid, listPermissionsRequest, listPermissionsHeaders,
          new RuntimeOptions());

      List<ListPermissionsResponseBodyPermissions> result = new ArrayList<>();
      while (resp.getStatusCode() == HttpStatus.HTTP_OK) {
        if (resp.getBody() != null && !resp.getBody().getPermissions().isEmpty()) {
          result.addAll(resp.getBody().getPermissions());
        }
        if (StringUtils.isBlank(resp.getBody().getNextToken())) {
          break;
        }
        option.setNextToken(resp.getBody().getNextToken());
        resp = client.listPermissionsWithOptions(
            dentryUuid, listPermissionsRequest, listPermissionsHeaders,
            new RuntimeOptions());
      }
      return result;
    } catch (Exception e) {
      log.error("错误消息：{}", e.getMessage(), e);
    }
    return null;
  }
}